package br.ufpe.cin.camid.core.lifecycle;

import br.ufpe.cin.camid.core.lifecycle.factory.ManagedObjectCreationException;
import br.ufpe.cin.camid.core.lifecycle.factory.ManagedObjectFactory;
import br.ufpe.cin.camid.core.objects.BlockingAcquireStrategy;
import br.ufpe.cin.camid.core.objects.ManagedObjectHandler;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;

@Singleton
public class StatefulObjectManager implements ObjectManager {

	private ManagedObjectFactory factory;
	
	private ObjectRegistry registry;
	
	
	@Inject
	public StatefulObjectManager(ManagedObjectFactory factory, ObjectRegistry registry, Injector injector)
	{
		this.factory = factory;
		this.registry = registry;
	}
	
	@Override
	public ManagedObjectHandler create(String objectId, Class<?> concreteClass) 
	{
		ManagedObjectHandler handler = registry.find(objectId);
		if(handler == null)
		{
			handler = factory.createObjectHandlerFromDefinition(objectId, concreteClass, new BlockingAcquireStrategy());
			registry.add(handler);
		}
		else
		{
			throw new ManagedObjectCreationException(String.format("Error trying to create object with ID %s and class %s: Object with same ID already exists", 
					objectId, concreteClass.getCanonicalName()));
		}
		
		return handler;
	}

	@Override
	public ManagedObjectHandler find(String objectId) 
	{
		ManagedObjectHandler handler = registry.find(objectId);
		return handler;
	}

	@Override
	public ManagedObjectHandler remove(String objectId) 
	{
		ManagedObjectHandler handler = registry.remove(objectId);
		return handler;
	}

	@Override
	public ManagedObjectHandler insert(String objectId, Object object) 
	{
		if(registry.contains(objectId))
		{
			throw new ManagedObjectCreationException(String.format("Insertion error: object with %s already exists", objectId)); 
		}
		
		ManagedObjectHandler handler = factory.createObjectHandlerFromInstance(objectId, object, new BlockingAcquireStrategy());
		registry.add(handler);
		
		return handler;
	}

}
